package org.hackystat.sensor.manual.devtime;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.xml.datatype.XMLGregorianCalendar;
import net.miginfocom.swing.MigLayout;
import org.hackystat.sensorbase.client.SensorBaseClient;
import org.hackystat.sensorbase.client.SensorBaseClientException;
import org.hackystat.sensorbase.resource.sensordata.jaxb.Property;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataIndex;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataRef;
import org.hackystat.utilities.tstamp.Tstamp;

/**
 * @author Shaoxuan Zhang
 *
 */
public class HistoryPanel extends JPanel {
  /** Support Serialization.*/
  private static final long serialVersionUID = 2843704741407406294L;
  

  /** The time format.*/
  private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
  private JFormattedTextField dateTextField;
  private JTextField toolTextField;
  private JTable dataTable;

  private SensorBaseClient client;
  private String userEmail;
  private SensorDataTableModel dataModel = new SensorDataTableModel();
  private SensorManager manager;
  
  /**
   * Construct this instance with the client information from the given SensorManager.
   * @param manager the sensor manager.
   */
  public HistoryPanel(SensorManager manager) {
    super(new MigLayout(HackyReporter.LAYOUT_MODE, "[grow,fill]", "[grow,fill]"));

    this.manager = manager;
    dataTable = new JTable(dataModel);
    //table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    dataTable.getColumnModel().getColumn(0).setPreferredWidth(35);
    dataTable.getColumnModel().getColumn(2).setPreferredWidth(100);
    //add(table, "span");        
    //table.setFillsViewportHeight(true);        
    JScrollPane scrollPane = new JScrollPane(dataTable);
    scrollPane.setPreferredSize(new Dimension(10, 5));
    add(scrollPane);
    
    JPanel headPanel = new JPanel(new MigLayout(HackyReporter.LAYOUT_MODE, // Layout Constraints 
        "rel[][]10[][grow,fill]rel",  // Column constraints 
        "rel[]rel")                       // Row constraints
    );          
    add(headPanel, "NORTH");      
    
    String host = manager.sensorShell.getProperties().getSensorBaseHost();
    userEmail = manager.sensorShell.getProperties().getSensorBaseUser();
    String password = manager.sensorShell.getProperties().getSensorBasePassword();
    client = new SensorBaseClient(host, userEmail, password);

    headPanel.add(new JLabel("Date"));
    dateTextField = new JFormattedTextField(dateFormat);
    dateTextField.setName("date");
    dateTextField.setText(dateFormat.format(new Date()));
    headPanel.add(dateTextField);

    headPanel.add(new JLabel("Tool"));
    toolTextField = new JTextField();
    toolTextField.setName("tool");
    headPanel.add(toolTextField);

    

    JPanel bottomPanel = new JPanel(new MigLayout(HackyReporter.LAYOUT_MODE, // Layout Constraints 
        "[center,grow,fill]20[center,grow,fill]",  // Column constraints 
        "rel[]rel")                       // Row constraints
    );          
    add(bottomPanel, "SOUTH");      

    JButton submitButton = new JButton("Refresh");
    submitButton.setName("refresh");
    submitButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        refreshData();
        dataTable.repaint();
        repaint();
      }
    });
    bottomPanel.add(submitButton);
    
    JButton deleteButton = new JButton("Delete");
    deleteButton.setName("delete");
    deleteButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        deleteDate(dataModel.removeData(dataTable.getSelectedRows()));
        dataTable.repaint();
      }
    });
    bottomPanel.add(deleteButton, "wrap");
    
  }

  /**
   * Delete data from sensorbase.
   * @param removedDate the data to be deleted.
   */
  protected void deleteDate(List<SensorData> removedDate) {
    String ownerEmail = userEmail;
    try {
      for (SensorData data : removedDate) {
        client.deleteSensorData(ownerEmail, data.getTimestamp());
      }
    }
    catch (SensorBaseClientException e) {
      manager.setStatusMessage(e.getMessage());
    }
  }

  /**
   * Refresh the table content.
   */
  private void refreshData() {
    Date date;
    String tool = toolTextField.getText();
    try {
      date = dateFormat.parse(dateTextField.getText());
    }
    catch (ParseException e) {
      dateTextField.setText(dateFormat.format(new Date()));
      return;
    }
    List<SensorData> sensorData = this.dataModel.getSensorData();
    sensorData.clear();
    XMLGregorianCalendar startTime = Tstamp.makeTimestamp(date.getTime());
    XMLGregorianCalendar endTime = Tstamp.incrementDays(startTime, 1);
    try {
      SensorDataIndex index;
      if (tool != null && tool.length() > 0) {
        manager.setStatusMessage("Retriving data of " + tool + " from Hackystat SensorBase.");
        index = 
          client.getProjectSensorData(userEmail, "Default", startTime, endTime, "DevTime", tool);
      }
      else {
        manager.setStatusMessage("Retriving data from Hackystat SensorBase.");
        index = client.getProjectSensorData(userEmail, "Default", startTime, endTime);
      }
      for (SensorDataRef ref : index.getSensorDataRef()) {
        sensorData.add(client.getSensorData(ref));
      }
      //System.out.println(sensorData.size() + " data instances retrieved.");
    }
    catch (SensorBaseClientException e) {
      // TODO Auto-generated catch block
      manager.setStatusMessage(e.getMessage());
    }
    List<SensorData> selfReportData = new ArrayList<SensorData>();
    for (SensorData data : sensorData) {
      for (Property property : data.getProperties().getProperty()) {
        if (SensorManager.SELF_REPORT_PROPERTY.equals(property.getKey()) && 
            "true".equals(property.getValue())) {
          selfReportData.add(data);
          break;
        }
      }
    }
    sensorData.retainAll(selfReportData);
    
    if (sensorData.isEmpty()) {
      manager.setStatusMessage("No manual report data found.");
    }
    else if (tool != null && tool.length() > 0) {
      manager.setStatusMessage(sensorData.size() + " data for \"" + tool + "\" found.");
    }
    else {
      manager.setStatusMessage(sensorData.size() + " data found.");
    }
    dataTable.updateUI();
    //dataTable.repaint();
    //repaint();
  }

}
